home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Online / SpeakFreely / src / CONTRIB / xspeakfree-0.7 / lib / xspeakfree / gui.tcl < prev    next >
Text File  |  2000-05-18  |  25KB  |  705 lines

  1. proc GUI_print {args} {
  2.     global GUI_status
  3.     
  4.     regsub -all "\t" [join $args] {    } x
  5.  
  6.     foreach i [split $x "\n"] {
  7.         $GUI_status insert end $i
  8.     }
  9.     $GUI_status see end
  10. }
  11.  
  12. proc GUI_connection_new { {noconnect {}} } {
  13.     global Mike GUI_hostlist_l
  14.  
  15.     if {$noconnect == {}} {
  16.         set host [GUI_askdialog .askdialog {Send Audio to Remote Host} {Send Audio to Remote Host:} 20 {}]
  17.     } else {
  18.         set host [GUI_askdialog .askdialog {Add Host} {Add Host:} 20 {}]
  19.     }
  20.     set host [string trim $host]
  21.  
  22.     if {$host != {} && $host != $Mike(target)} {
  23.         GUI_hostlist add $host
  24.         if {$noconnect == {}} {
  25.             $GUI_hostlist_l selection clear 0 end
  26.             $GUI_hostlist_l selection set end
  27.             set Mike(target) $host
  28.             ControlMike open
  29.         }
  30.     }
  31. }
  32.  
  33. proc GUI_hostlist {cmd {host {}} args} {
  34.     global GUI_hostlist_l Mike HostListConstants GUI_hostlist_values
  35.     
  36.     if {$cmd == {clear}} {
  37.         unset GUI_hostlist_values
  38.         $GUI_hostlist_l delete 0 end
  39.  
  40.         foreach {n l} $HostListConstants {
  41.             GUI_hostlist add $n -comment $l
  42.         }
  43.  
  44.         return
  45.     }
  46.  
  47.     if {$cmd == {get}} {
  48.         set n [string trim $args {- }]
  49.         return $GUI_hostlist_values($host:$n)
  50.     }
  51.     if {$cmd == {varget}} {
  52.         set r {}
  53.         catch {set r $GUI_hostlist_values($host:[string trim $args])}
  54.         return $r
  55.     }
  56.     if {$cmd == {varset}} {
  57.         return [set GUI_hostlist_values($host:[string trim [lindex $args 0]]) [lindex $args 1]]
  58.     }
  59.     if {$cmd == {host}} {
  60.         return [lindex [string trimleft [$GUI_hostlist_l get $host] { +}] 0]
  61.     }
  62.  
  63.     set comment {}; set comments 0
  64.     set xmit {}; set xmits 0
  65.     set sound {}; set sounds 0
  66.     set connection false; set connections 0
  67.     foreach {n v} $args {
  68.         switch -exact -- $n {
  69.             -comment {set comment $v; set comments 1}
  70.             -transmit {set xmit $v; set xmits 1}
  71.             -sound {set sound $v; set sounds 1}
  72.             -connection {set connection $v; set connections 1}
  73.         }
  74.     }
  75.  
  76.     set host [string tolower $host]
  77.  
  78.     if {[array get GUI_hostlist_values "$host:*"] != {}} {
  79.         if {$cmd == {add}} { set cmd {edit} }
  80.  
  81.         if {!$comments} { set comment $GUI_hostlist_values($host:comment) }
  82.         if {!$sounds} { set sound $GUI_hostlist_values($host:sound) }
  83.         if {!$xmits} { set xmit $GUI_hostlist_values($host:xmit) }
  84.     }
  85.  
  86.     if {$xmit == {+} || $xmit == {true}} { set xmit {+} } else { set xmit { } }
  87.  
  88.     set label [format {%-1.1s %-30.30s  %-20.20s  %-20.20s} $xmit $host $comment $sound]
  89.  
  90.     set GUI_hostlist_values($host:comment) $comment
  91.     set GUI_hostlist_values($host:sound) $sound
  92.     set GUI_hostlist_values($host:xmit) $xmit
  93.  
  94.     if {$cmd == {edit}} {
  95.         for {set i 0; set end [$GUI_hostlist_l size]} {$i < $end} {incr i} {
  96.             if {[lindex [string trimleft [$GUI_hostlist_l get $i] { +}] 0] == $host} {
  97.                 $GUI_hostlist_l delete $i
  98.                 $GUI_hostlist_l insert $i $label
  99.             }
  100.         }
  101.     }
  102.  
  103.     if {$cmd == {add}} {
  104.         set insert 1
  105.  
  106.         for {set i 0; set end [$GUI_hostlist_l size]} {$i < $end} {incr i} {
  107.             if {[lindex [string trimleft [$GUI_hostlist_l get $i] { +}] 0] == $host} { set insert 0 }
  108.         }
  109.  
  110.         if {$insert == 1} {
  111.             $GUI_hostlist_l insert end $label
  112.         }
  113.         if {$connection} {
  114.             if {$Mike(hostlist:add:send_busy) == 1 && $Mike(target) != {}} {
  115.                 SendSoundFile $host busy
  116.             } else {
  117.                 if {$host != {localhost} && $Mike(hostlist:add:play_ring) == 1} {
  118.                     SendSoundFile localhost ring noprint
  119.                 }
  120.             }
  121.         }
  122.     }
  123.  
  124.     if {$cmd == {remove}} {
  125.         if {$Mike(target) == $host} { return }
  126.  
  127.         foreach n [array names GUI_hostlist_values "$host:*"] {
  128.             catch {unset GUI_hostlist_values($n) }
  129.         }
  130.         
  131.         foreach {n l} $HostListConstants { if {$n == $host} { return } }
  132.  
  133.         for {set i 0; set end [$GUI_hostlist_l size]} {$i < $end} {incr i} {
  134.             if {[lindex [string trimleft [$GUI_hostlist_l get $i] { +}] 0] == $host} {
  135.                 $GUI_hostlist_l delete $i
  136.             }
  137.         }
  138.     }
  139. }
  140.  
  141. proc GUI_set_menu_item_state { menu item state } {
  142.     global GUI_info
  143.     
  144.     foreach {m id} $GUI_info($menu:$item) {
  145.         $m entryconfigure $id -state $state
  146.     }
  147. }
  148.  
  149. proc GUI_draw {} {
  150.     global GUI_hostlist_l GUI_info GUI_status HostListConstants GUI_hostlist_label
  151.  
  152.     wm title . xspeakfree
  153.     bind . <Destroy> {Exit}
  154.     wm protocol . WM_DELETE_WINDOW {destroy .}
  155.  
  156.     set fixed1 {-*-fixed-*-*-*-*-10-*-*-*-*-*-*-*}
  157.  
  158.     frame .menubar -relief raised -border 2
  159.     pack .menubar -fill x
  160.  
  161.     set m .menubar.connection.m
  162.     menubutton .menubar.connection -text "Connection" -underline 0 -menu $m
  163.     menu $m -tearoff 0
  164.     $m add command -label "New..." -command GUI_connection_new
  165.     $m add command -label "Close" -command  {
  166.         ControlMike close
  167.         $GUI_hostlist_l selection clear 0 end    
  168.         } -state disabled
  169.     $m add command -label "Restart sfspeaker" -command { ControlSpeaker open }
  170.     $m add separator
  171.     $m add command -label "Play audio file..." -command {
  172.         set file [tk_getOpenFile]
  173.         if {$file != {}} {
  174.             GUI_hostlist add localhost -connection false -transmit false
  175.             SendSoundFile localhost $file
  176.         }
  177.     }
  178.     $m add separator
  179.     $m add command -label "Clear Status" -command { $GUI_status delete 0 end }
  180.     $m add command -label "Clear Target Host List" -command { GUI_hostlist clear }
  181.     $m add separator
  182.     $m add command -label "Exit" -command Exit
  183.     pack .menubar.connection -side left
  184.  
  185.     lappend GUI_info(connection:close) $m 1
  186.  
  187.     set m .menubar.options.m
  188.     menubutton .menubar.options -text "Options" -underline 0 -menu $m
  189.     menu $m -tearoff 0
  190.     $m add command -label "Local Port..." -command {
  191.         set lport [GUI_askdialog .askdialog {Local Port} {Local Port:} 10 $Speaker(port)]
  192.         if {$lport != $Speaker(port)} {
  193.             set Speaker(port) $lport
  194.             ControlSpeaker restart
  195.         }
  196.     }
  197.     $m add command -label "Encryption Options..." -command {
  198.         if {[newdialog -path .askdialog -title {Encryption Options} -create {
  199.             global Speaker
  200.  
  201.             label $w.l -text "Encryption Options"
  202.             pack $w.l -ipadx 10 -ipady 10 -side top
  203.  
  204.             frame $w.f1
  205.             label $w.f1.l -text "Encryption Method:"
  206.             radiobutton $w.f1.r0 -text "None" -value { } -variable Speaker(:crypt:method)
  207.             radiobutton $w.f1.r1 -text "IDEA" -value {-I} -variable Speaker(:crypt:method)
  208.             radiobutton $w.f1.r2 -text "DES" -value {-K} -variable Speaker(:crypt:method)
  209.             radiobutton $w.f1.r3 -text "File" -value {-O} -variable Speaker(:crypt:method)
  210.             radiobutton $w.f1.r4 -text "PGP" -value {-Z} -variable Speaker(:crypt:method)
  211.             pack $w.f1.l -side left -anchor w
  212.             pack $w.f1.r0 -side left -anchor w
  213.             pack $w.f1.r1 -side left -anchor w
  214.             pack $w.f1.r2 -side left -anchor w
  215.             pack $w.f1.r3 -side left -anchor w
  216.             pack $w.f1.r4 -side left -anchor w
  217.             pack $w.f1 -anchor w
  218.             
  219.             frame $w.f2
  220.             frame $w.f2.fl
  221.             frame $w.f2.fr
  222.             
  223.             label $w.f2.fl.l1 -text "IDEA Key:"
  224.             pack $w.f2.fl.l1 -anchor w
  225.             label $w.f2.fl.l2 -text "DES Key:"
  226.             pack $w.f2.fl.l2 -anchor w
  227.             label $w.f2.fl.l3 -text "File:"
  228.             pack $w.f2.fl.l3 -anchor w
  229.             label $w.f2.fl.l4 -text "PGP Pass Phrase:"
  230.             pack $w.f2.fl.l4 -anchor w
  231.             
  232.             entry $w.f2.fr.e1 -textvariable Speaker(:crypt:-I) -width 40
  233.             pack $w.f2.fr.e1 -anchor w
  234.             entry $w.f2.fr.e2 -textvariable Speaker(:crypt:-K) -width 40
  235.             pack $w.f2.fr.e2 -anchor w
  236.             frame $w.f2.fr.f1
  237.             entry $w.f2.fr.f1.e3 -textvariable Speaker(:crypt:-O) -width 25
  238.             button $w.f2.fr.f1.b1 -text "Select File" -command {
  239.                     set f [ tk_getOpenFile -title {Crypt file:} -initialfile [file tail $Speaker(:crypt:-O)] -initialdir [file dirname $Speaker(:crypt:-O)] ]
  240.                     if {$f != {}} {
  241.                         set Speaker(:crypt:-O) $f
  242.                     }
  243.                 }
  244.             pack $w.f2.fr.f1.e3 -side left -anchor w
  245.             pack $w.f2.fr.f1.b1 -side left -anchor w
  246.             pack $w.f2.fr.f1 -anchor w
  247.             entry $w.f2.fr.e4 -textvariable Speaker(:crypt:-Z) -width 40
  248.             pack $w.f2.fr.e4 -anchor w
  249.             
  250.             pack $w.f2.fl -side left
  251.             pack $w.f2.fr -side right
  252.             pack $w.f2
  253.  
  254.             button $w.b1 -text "Ok" -command {set GUI_pri_buttonValue 1}
  255.             pack $w.b1 -side bottom -anchor se
  256.  
  257.         } -variable GUI_pri_buttonValue] == 1} {
  258.             ModifyArgs Speaker
  259.             ModifyArgs Mike
  260.         }
  261.     }
  262.     $m add cascade -label "Jitter Compensation" -menu .menubar.options.m.jitter
  263.     $m add checkbutton -label "Disable Remote Ring Requests" -command {ModifyArgs Speaker} -onvalue {-n} -offvalue { } -variable Speaker(args:disable_remote_ring)
  264.     $m add command -label "Record Audio To File ..." -command {
  265.         if {[newdialog -path .askdialog -title {Record Audio To File} -create {
  266.                 global Speaker
  267.  
  268.                 label $w.l -text "Record Audio To File"
  269.                 pack $w.l -ipadx 10 -ipady 10 -side top
  270.                 
  271.                 frame $w.f3
  272.                 label $w.f3.l -text "Record Audio:"
  273.                 radiobutton $w.f3.r1 -text "Yes" -value 1 -variable Speaker(:record:onoff) -command "
  274.                     $w.f2.r1 configure -state normal
  275.                     $w.f2.r2 configure -state normal
  276.                     $w.f.b configure -state normal
  277.                     $w.f.v configure -fg black
  278.                     $w.f.l configure -fg black
  279.                 "
  280.                 radiobutton $w.f3.r2 -text "No" -value 0 -variable Speaker(:record:onoff) -command "
  281.                     $w.f2.r1 configure -state disabled
  282.                     $w.f2.r2 configure -state disabled
  283.                     $w.f.b configure -state disabled
  284.                     $w.f.v configure -fg grey
  285.                     $w.f.l configure -fg grey
  286.                 "
  287.                 pack $w.f3.l -side left -anchor w
  288.                 pack $w.f3.r1 -side left -anchor w
  289.                 pack $w.f3.r2 -side left -anchor w
  290.                 pack $w.f3
  291.                 
  292.                 frame $w.fp1
  293.                 pack $w.fp1 -ipady 20
  294.  
  295.                 frame $w.f
  296.                 label $w.f.l -text "Record into:"
  297.                 pack $w.f.l -side left -anchor w
  298.                 label $w.f.v -textvariable Speaker(:record:file)
  299.                 pack $w.f.v -side left -anchor w
  300.  
  301.                 button $w.f.b -text "Select File" -command {
  302.                     set f [ tk_getSaveFile -title {Record into:} -initialfile [file tail $Speaker(:record:file)] -initialdir [file dirname $Speaker(:record:file)] ]
  303.                     if {$f != {}} {
  304.                         set Speaker(:record:file) $f
  305.                     }
  306.                 }
  307.                 pack $w.f.b -side right -anchor w
  308.                 pack $w.f
  309.  
  310.                 frame $w.f2
  311.                 radiobutton $w.f2.r1 -text "Overwrite file" -value {} -variable Speaker(:record:append)
  312.                 radiobutton $w.f2.r2 -text "Append to file" -value {+} -variable Speaker(:record:append)
  313.                 pack $w.f2.r1 -side right -anchor w
  314.                 pack $w.f2.r2 -side right -anchor w
  315.                 pack $w.f2
  316.  
  317.                 frame $w.fp
  318.                 pack $w.fp -ipady 20
  319.  
  320.                 if {$Speaker(:record:onoff) == 0} {
  321.                     $w.f2.r1 configure -state disabled
  322.                     $w.f2.r2 configure -state disabled
  323.                     $w.f.b configure -state disabled
  324.                     $w.f.v configure -fg grey
  325.                     $w.f.l configure -fg grey
  326.                 }
  327.  
  328.                 
  329.                 frame $w.fb
  330.                 button $w.fb.b1 -text "Ok" -command { 
  331.                     if {$Speaker(:record:file) == {}} {
  332.                         set GUI_pri_buttonValue 2
  333.                     } else {
  334.                         set GUI_pri_buttonValue 1
  335.                     }
  336.                 }
  337.                 button $w.fb.b2 -text "Cancel" -command { set GUI_pri_buttonValue 2 }
  338.                 pack $w.fb.b1 -anchor se -side right
  339.                 pack $w.fb.b2 -anchor sw -side left
  340.                 pack $w.fb
  341.  
  342.                 set buttonValue 0
  343.             } -variable GUI_pri_buttonValue] == 1} {
  344.             ModifyArgs Speaker
  345.         }
  346.     }
  347.     $m add command -label "Additional sfspeaker Arguments..." -command {
  348.         set f [GUI_askdialog .askdialog {sfspeaker arguments} {Additional sfspeaker arguments} 20 $Speaker(args:user)]
  349.         if {$f != $Speaker(args:user)} {
  350.             set Speaker(args:user) $f
  351.             ModifyArgs Speaker
  352.         }
  353.     }
  354.     $m add separator
  355.     $m add cascade -label "Compression" -menu .menubar.options.m.compression
  356.     $m add cascade -label "Transmission Protocol" -menu .menubar.options.m.protocol
  357.     $m add checkbutton -label "Send Remote Ring" -command {ModifyArgs Mike} -onvalue {-R} -offvalue { } -variable Mike(args:ring)
  358.     $m add command -label "Additional sfmike Arguments..." -command {
  359.         set f [GUI_askdialog .askdialog {sfmike arguments} {Additional sfmike arguments} 20 $Mike(args:user)]
  360.         if {$f != $Mike(args:user)} {
  361.             set Mike(args:user) $f
  362.             ModifyArgs Mike
  363.         }
  364.     }
  365.     $m add separator
  366.     $m add checkbutton -label "Send Ring Sound To Targets" -onvalue 1 -offvalue 0 -variable Mike(connect:send_ring)
  367.     $m add separator
  368.     $m add checkbutton -label "Sound Ring For New Connections" -onvalue 1 -offvalue 0 -variable Mike(hostlist:add:play_ring)
  369.     $m add checkbutton -label "Send Busy Signal If Already Connected" -onvalue 1 -offvalue 0 -variable Mike(hostlist:add:send_busy)
  370.     $m add separator
  371.     $m add command -label "LWL Information..." -command {
  372.         if {[newdialog -path .askdialog -title {LWL Information} -create {
  373.             global lwli env
  374.             if {[array get env SPEAKFREE_ID] == {}} {
  375.                 set lwlinfo [list {} {} {} {}]
  376.             } else {
  377.                 set lwlinfo [split $env(SPEAKFREE_ID) {:}]
  378.             }
  379.             catch {unset lwli}
  380.             set lwli(name) [lindex $lwlinfo 0]
  381.             set lwli(email) [lindex $lwlinfo 1]
  382.             set lwli(phone) [lindex $lwlinfo 2]
  383.             set lwli(location) [lindex $lwlinfo 3]
  384.             set lwli(hosts) {lwl.fourmilab.ch}
  385.             catch {set lwli(hosts) $env(SPEAKFREE_LWL_TELL)}
  386.  
  387.             label $w.l -text "LWL Information"
  388.             pack $w.l -ipadx 10 -ipady 10 -side top
  389.  
  390.             frame $w.f2
  391.             frame $w.f2.fl
  392.             frame $w.f2.fr
  393.             
  394.             label $w.f2.fl.l1 -text "Full Name:"
  395.             pack $w.f2.fl.l1 -anchor w
  396.             label $w.f2.fl.l2 -text "Email:"
  397.             pack $w.f2.fl.l2 -anchor w
  398.             label $w.f2.fl.l3 -text "Phone:"
  399.             pack $w.f2.fl.l3 -anchor w
  400.             label $w.f2.fl.l4 -text "Location:"
  401.             pack $w.f2.fl.l4 -anchor w
  402.             label $w.f2.fl.l5 -text "Tell Hosts:"
  403.             pack $w.f2.fl.l5 -anchor w
  404.             
  405.             entry $w.f2.fr.e1 -textvariable lwli(name) -width 40
  406.             pack $w.f2.fr.e1 -anchor w
  407.             entry $w.f2.fr.e2 -textvariable lwli(email) -width 40
  408.             pack $w.f2.fr.e2 -anchor w
  409.             entry $w.f2.fr.e3 -textvariable lwli(phone) -width 40
  410.             pack $w.f2.fr.e3 -anchor w
  411.             entry $w.f2.fr.e4 -textvariable lwli(location) -width 40
  412.             pack $w.f2.fr.e4 -anchor w
  413.             entry $w.f2.fr.e5 -textvariable lwli(hosts) -width 40
  414.             pack $w.f2.fr.e5 -anchor w
  415.             
  416.             pack $w.f2.fl -side left
  417.             pack $w.f2.fr -side right
  418.             pack $w.f2
  419.  
  420.             button $w.b1 -text "Ok" -command {set GUI_pri_buttonValue 1}
  421.             pack $w.b1 -side bottom -anchor se
  422.  
  423.         } -variable GUI_pri_buttonValue] == 1} {
  424.             global lwli env
  425.  
  426.             set env(SPEAKFREE_LWL_TELL) $lwli(hosts)
  427.             set env(SPEAKFREE_ID) "$lwli(name):$lwli(email):$lwli(phone):$lwli(location)"
  428.             if {$env(SPEAKFREE_LWL_TELL) == {}} { catch {unset env(SPEAKFREE_LWL_TELL)} }
  429.             if {$env(SPEAKFREE_ID) == {:::}} { catch {unset env(SPEAKFREE_ID)} }
  430.  
  431.             ControlSpeaker restart
  432.         }
  433.     }
  434.     pack .menubar.options -side left
  435.  
  436.     set m .menubar.options.m.compression
  437.     menu $m -tearoff 0
  438.     $m add checkbutton -label "Simple Compression" -command {ModifyArgs Mike} -onvalue {-C} -offvalue { } -variable Mike(args:simplecompression)
  439.     $m add radiobutton -label "No Compression" -command {ModifyArgs Mike} -value {-N} -variable Mike(args:compression)
  440.     $m add radiobutton -label "GSM Compression" -command {ModifyArgs Mike} -value {-T} -variable Mike(args:compression)
  441.     $m add radiobutton -label "ADPCM Compression" -command {ModifyArgs Mike} -value {-F} -variable Mike(args:compression)
  442.     $m add radiobutton -label "LPC Compression" -command {ModifyArgs Mike} -value {-LPC} -variable Mike(args:compression)
  443.     $m add radiobutton -label "LPC-10 1x Compression" -command {ModifyArgs Mike} -value {-LPC10R1} -variable Mike(args:compression)
  444.     $m add radiobutton -label "LPC-10 2x Compression" -command {ModifyArgs Mike} -value {-LPC10R2} -variable Mike(args:compression)
  445.     $m add radiobutton -label "LPC-10 3x Compression" -command {ModifyArgs Mike} -value {-LPC10R3} -variable Mike(args:compression)
  446.     $m add radiobutton -label "LPC-10 4x Compression" -command {ModifyArgs Mike} -value {-LPC10R4} -variable Mike(args:compression)
  447.  
  448.     set m .menubar.options.m.jitter
  449.     menu $m -tearoff 0
  450.     $m add radiobutton -label "None" -command {ModifyArgs Speaker} -value " " -variable Speaker(args:jitter)
  451.     $m add separator
  452.     $m add radiobutton -label "1/10 Second" -command {ModifyArgs Speaker} -value "-J100" -variable Speaker(args:jitter)
  453.     $m add radiobutton -label "1/4 Second" -command {ModifyArgs Speaker} -value "-J250" -variable Speaker(args:jitter)
  454.     $m add radiobutton -label "1/2 Second" -command {ModifyArgs Speaker} -value "-J500" -variable Speaker(args:jitter)
  455.     $m add radiobutton -label "3/4 Second" -command {ModifyArgs Speaker} -value "-J750" -variable Speaker(args:jitter)
  456.     $m add radiobutton -label "1 Second" -command {ModifyArgs Speaker} -value "-J1000" -variable Speaker(args:jitter)
  457.     $m add radiobutton -label "2 Seconds" -command {ModifyArgs Speaker} -value "-J2000" -variable Speaker(args:jitter)
  458.     $m add radiobutton -label "3 Seconds" -command {ModifyArgs Speaker} -value "-J3000" -variable Speaker(args:jitter)
  459.  
  460.     set m .menubar.options.m.protocol
  461.     menu $m -tearoff 0
  462.     $m add radiobutton -label "Speak Freely" -command {ModifyArgs Mike} -value " " -variable Mike(args:protocol)
  463.     $m add radiobutton -label "Real Time Protocol (RTP)" -command {ModifyArgs Mike} -value "-RTP" -variable Mike(args:protocol)
  464.     $m add radiobutton -label "Visual Audio Tool (VAT)" -command {ModifyArgs Mike} -value "-VAT" -variable Mike(args:protocol)
  465.  
  466.     if {[GetOS] == "IRIX"} {
  467.         set m .menubar.irix.m
  468.         menubutton .menubar.irix -text "Irix" -underline 0 -menu $m
  469.         menu $m -tearoff 0
  470.         $m add command -label "Audio Panel" -command {
  471.             GUI_print "Opening Audio Panel"
  472.             exec apanel & }
  473.         pack .menubar.irix -side left
  474.     }
  475.  
  476.     set m .menubar.help.m
  477.     menubutton .menubar.help -text "Help" -underline 0 -menu $m
  478.     menu $m -tearoff 0
  479.     $m add command -label About -command GUI_help_about
  480.     $m add separator
  481.     $m add command -label {wish Version} -command {
  482.         GUI_print "\n    Tcl version: $tcl_patchLevel"
  483.         GUI_print "    Tk version: $tk_patchLevel\n"
  484.     }
  485.     $m add command -label {Speak Freely Version} -command {
  486.         set id [open_exec -command {sfmike -U} -stdout fd]
  487.         gets $fd line
  488.         gets $fd line
  489.         close_exec $id
  490.         GUI_print "\n    Speak Freely version: [string trim $line]\n"
  491.     }
  492.     $m add separator
  493.     $m add command -label {Speak Freely for Unix} -command {
  494.         GUI_print "\n    Speak Freely for Unix:.\n    Please see the Web Page at:\n\t\thttp://www.fourmilab.ch/speakfree/unix/\n"
  495.     }
  496.     pack .menubar.help -side right -anchor e
  497.  
  498.     frame .status
  499.     label .status.l -text "Session Status: "
  500.     listbox .status.v -height 7 -width 60 -yscrollcommand {.status.sy set} -xscrollcommand {.status.sx set} -selectmode browse -exportselection true
  501.     scrollbar .status.sy -command {.status.v yview}
  502.     scrollbar .status.sx -command {.status.v xview} -orient horizontal
  503.     pack .status.l -anchor nw
  504.     pack .status.sy -fill y -expand 0 -anchor e -side right
  505.     pack .status.sx -fill x -expand 0 -anchor s -side bottom
  506.     pack .status.v -fill both -expand 1 -anchor nw -side left
  507.     set GUI_status .status.v
  508.  
  509.     frame .hosts
  510.     label .hosts.l -text "Host List: "
  511.  
  512.     listbox .hosts.lt -width 76 -height 1 -font $fixed1
  513.     .hosts.lt insert end [format {  %-30.30s  %-20.20s  %-20.20s} {DNS / IP} {Comment} {Sound file}]
  514.     bindtags .hosts.lt {.hosts.lt}
  515.     proc GUI_hosts_lt_scroll {x j} {
  516.         .hosts.lt xview moveto $x
  517.     }
  518.  
  519.     set GUI_hostlist_l .hosts.v
  520.     listbox $GUI_hostlist_l -width 76 -height 5 -yscrollcommand {.hosts.sy set} -font $fixed1 -selectmode single -xscrollcommand {GUI_hosts_lt_scroll}
  521.     scrollbar .hosts.sy -command "$GUI_hostlist_l yview"
  522.  
  523.     foreach {n l} $HostListConstants {
  524.         GUI_hostlist add $n $l
  525.     }
  526.     pack .hosts.l -anchor nw
  527.     pack .hosts.lt -anchor nw
  528.     pack .hosts.sy -fill y -anchor e -side right
  529.     pack .hosts.v -fill both -anchor nw -side left
  530.     #bind .hosts.v <Button-1> {}
  531.     bindtags .hosts.v {. Listbox all}
  532.     set m .hosts.vm
  533.     menu $m -tearoff 0
  534.     $m add command -label "Add host" -command { GUI_connection_new noconnect }
  535.     $m add command -label "Connect to host" -command {
  536.         set h [GUI_hostlist host $GUI_hostlist_l_i]
  537.         if {$h != {} && $h != $Mike(target)} {
  538.             set Mike(target) $h;
  539.             $GUI_hostlist_l selection clear 0 end
  540.             $GUI_hostlist_l selection set $GUI_hostlist_l_i
  541.             ControlMike open
  542.         }
  543.     }
  544.     $m add command -label "Close current connection" -command { ControlMike close } -state disabled
  545.     $m add separator
  546.     $m add command -label "Send busy" -command {
  547.         set h [GUI_hostlist host $GUI_hostlist_l_i]
  548.         SendSoundFile $h busy
  549.     }
  550.     $m add command -label "Send ring" -command {
  551.         set h [GUI_hostlist host $GUI_hostlist_l_i]
  552.         SendSoundFile $h ring
  553.     }
  554.     $m add command -label "Send sound file..." -command {
  555.         set h [GUI_hostlist host $GUI_hostlist_l_i]
  556.         set file [tk_getOpenFile -title "Select sound file to send to $h"]
  557.         if {$file != {}} {
  558.             SendSoundFile $h $file
  559.         }
  560.     }
  561.     $m add command -label "Stop sound files" -command {
  562.         set h [GUI_hostlist host $GUI_hostlist_l_i]
  563.         foreach x [GUI_hostlist varget $h {sendsnd:exec}] {
  564.             close_exec $x
  565.         }
  566.         GUI_hostlist edit $h -sound {}
  567.         GUI_hostlist varset $h {sendsnd:exec} {}
  568.     }
  569.     $m add separator
  570.     $m add command -label "Edit comment" -command {
  571.         set h [GUI_hostlist host $GUI_hostlist_l_i]
  572.         GUI_hostlist edit $h -comment [GUI_askdialog .askdialog "Comment for $h" "Comment for $h:" 20 [GUI_hostlist get $h -comment]]
  573.     }
  574.     $m add command -label "Remove host" -command {
  575.         if {$Mike(target) != [GUI_hostlist host $GUI_hostlist_l_i]} {
  576.             $GUI_hostlist_l delete $GUI_hostlist_l_i
  577.         }
  578.     }
  579.  
  580.     lappend GUI_info(connection:close) $m 2
  581.     lappend GUI_info(hostlist:host) $m 1 $m 4 $m 5 $m 6 $m 9 $m 10
  582.     lappend GUI_info(hostlist:blank)
  583.     lappend GUI_info(hostlist:sound) $m 7
  584.  
  585.     bind . <Button-3> {
  586.         if {{%W} == {.hosts.v}} {
  587.             set GUI_hostlist_l_i [%W index @%x,%y]
  588.             set bbox [%W bbox $GUI_hostlist_l_i]
  589.             GUI_set_menu_item_state hostlist sound disabled
  590.             if {[lindex $bbox 1] <= %y && %y <= [expr [lindex $bbox 1] + [lindex $bbox 3]]} {
  591.                 GUI_set_menu_item_state hostlist blank disabled
  592.                 GUI_set_menu_item_state hostlist host normal
  593.                 if {[GUI_hostlist varget [GUI_hostlist host $GUI_hostlist_l_i] {sendsnd:exec}] != {}} {
  594.                     GUI_set_menu_item_state hostlist sound normal
  595.                 }
  596.             } else {
  597.                 GUI_set_menu_item_state hostlist host disabled
  598.                 GUI_set_menu_item_state hostlist blank normal
  599.             }
  600.         } else {
  601.             set GUI_hostlist_l_i -1
  602.             GUI_set_menu_item_state hostlist host disabled
  603.             GUI_set_menu_item_state hostlist blank normal
  604.             GUI_set_menu_item_state hostlist sound disabled
  605.         }
  606.         tk_popup .hosts.vm %X %Y
  607.     }
  608.  
  609.     frame .localport
  610.     label .localport.l -text "Local Port: "
  611.     label .localport.v -textvariable Speaker(port) -font $fixed1
  612.     pack .localport.l -side left
  613.     pack .localport.v
  614.  
  615.     frame .mike
  616.     frame .mike.buttons
  617.     frame .mike.status
  618.     frame .mike.status2
  619.  
  620.     label .mike.buttons.l -text "Microphone: "
  621.     radiobutton .mike.buttons.r0 -text "Full Mute" -variable Mike(:button) -value "Mute" -command { ControlMike off }
  622.     radiobutton .mike.buttons.r1 -text "Push Button 2 To Talk" -variable Mike(:button) -value "Push" -command {
  623.         if {$Mike(exec:id) == {} || $Mike(pri:ready) != 1} { set Mike(:button) "Mute" }
  624.         ControlMike off}
  625.     radiobutton .mike.buttons.r2 -text "Open" -variable Mike(:button) -value "Open" -command { 
  626.         if {$Mike(exec:id) == {} || $Mike(pri:ready) != 1 } { set Mike(:button) "Mute" }
  627.         ControlMike on }
  628.     pack .mike.buttons.l -side left
  629.     pack .mike.buttons.r0 -side left
  630.     pack .mike.buttons.r1 -side left
  631.     pack .mike.buttons.r2 -side left
  632.     bind . <ButtonPress-2> { if {$Mike(:button) == "Push"} { ControlMike on } }
  633.     bind . <ButtonRelease-2> { if {$Mike(:button) == "Push"} { ControlMike off } }
  634.  
  635.     label .mike.status.l -text "Microphone Status:"
  636.     label .mike.status.ms -textvariable Mike(:state:text) -font $fixed1 -width 10
  637.     pack .mike.status.l -side left
  638.     pack .mike.status.ms -side left
  639.  
  640.     label .mike.status.l2 -text "Microphone Transmitting To: "
  641.     label .mike.status.v2 -textvariable Mike(target) -font $fixed1
  642.     pack .mike.status.l2 -side left
  643.     pack .mike.status.v2 -side left
  644.  
  645.     pack .mike.buttons -side top -anchor w
  646.     pack .mike.status -side bottom -anchor w
  647.  
  648.     pack .localport -anchor nw
  649.     pack .mike -anchor nw
  650.     pack .hosts -anchor nw
  651.     pack .status -fill both -expand 1
  652. }
  653.  
  654. proc GUI_askdialog {w title text width value} {
  655.     return [newdialog -path $w -title $title -create {
  656.     upvar width width value value text text
  657.     frame $w.bot
  658.     frame $w.but
  659.     frame $w.top
  660.     $w.bot configure -relief raised -bd 1
  661.     $w.top configure -relief raised -bd 1
  662.     pack $w.top -fill both -expand 1
  663.     pack $w.bot -fill both
  664.     pack $w.but -fill both
  665.  
  666.     option add *Dialog.msg.wrapLength 3i widgetDefault
  667.     label $w.msg -justify left -text $text
  668.     pack $w.msg -in $w.top -side right -expand 1 -fill both -padx 3m -pady 3m
  669.  
  670.     text $w.bot.in -width $width -height 1
  671.     $w.bot.in insert insert $value
  672.     pack $w.bot.in -expand 1 -fill x
  673.  
  674.     button $w.but.button0 -text {Ok} -command {set GUI_pri_askdialog_waitvar 0}
  675.     button $w.but.button1 -text {Cancel} -command {set GUI_pri_askdialog_waitvar 1}
  676.  
  677.     pack $w.but.button1 -side left
  678.     pack $w.but.button0 -side right
  679.  
  680.     bind $w <Return> "
  681.         $w.but.button0 configure -state active -relief sunken
  682.         update idletasks
  683.         set GUI_pri_askdialog_waitvar 0
  684.     "
  685.     bind $w.bot.in <Return> "
  686.         $w.but.button0 configure -state active -relief sunken
  687.         update idletasks
  688.         after 100
  689.         set askdialog_waitvar 0
  690.     "} -variable GUI_pri_askdialog_waitvar -after {
  691.         if {$GUI_pri_askdialog_waitvar == 0} {
  692.             catch {set GUI_pri_askdialog_waitvar [string trim [$w.bot.in get 1.0 end]]}
  693.         } else {
  694.             set GUI_pri_askdialog_waitvar $value
  695.         }
  696.     }]
  697. }
  698.  
  699. proc GUI_help_about {} {
  700.     global XSpeakFreeVersion
  701.  
  702.     GUI_print "\n    xspeakfree version $XSpeakFreeVersion"
  703.     GUI_print "    Author: Shawn Pearce, <spearce@injersey.com>\n"
  704. }
  705.